package com.wzy.oa_sys.service.impl.report;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzy.oa_sys.mapper.attendance.TimeStandardMapper;
import com.wzy.oa_sys.mapper.log.LogMapper;
import com.wzy.oa_sys.mapper.report.WorkMapper;
import com.wzy.oa_sys.mapper.attendance.AttendanceMapper;
import com.wzy.oa_sys.mapper.user.DeptMapper;
import com.wzy.oa_sys.mapper.user.UserMapper;
import com.wzy.oa_sys.model.pojo.attendance.OaAttendance;
import com.wzy.oa_sys.model.pojo.attendance.OaTimeStandards;
import com.wzy.oa_sys.model.pojo.log.OaLog;
import com.wzy.oa_sys.model.pojo.report.OaWork;
import com.wzy.oa_sys.model.pojo.user.OaUser;
import com.wzy.oa_sys.model.response.report.PerformanceResp;
import com.wzy.oa_sys.model.response.report.TaskRateResp;
import com.wzy.oa_sys.model.response.report.UseSituationResp;
import com.wzy.oa_sys.model.response.report.WorkTimeResp;
import com.wzy.oa_sys.model.response.task.TaskResp;
import com.wzy.oa_sys.service.report.RePortService;
import com.wzy.oa_sys.service.task.TaskService;
import com.wzy.oa_sys.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Time;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements RePortService {

    //工作时间
    @Autowired
    private WorkMapper workMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TimeStandardMapper timeStandardMapper;
    @Autowired
    private LogMapper logMapper;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<WorkTimeResp> getWorkTime(HttpServletRequest request) {
        List<OaUser> oaUsers = userMapper.selectList(null);
        List<OaWork> oaWorks = workMapper.selectList(null);
        List<WorkTimeResp> workTimeResps = new ArrayList<WorkTimeResp>();
        HashSet<Long> userIds = new HashSet<Long>();
        String role = jwtUtil.extractUserRole(request);
        Long userId = jwtUtil.extractUserId(request);
        if(oaUsers.size() != 0){
            for (OaWork oaWork : oaWorks) {
                //能查到信息表示未离职
                if(userMapper.selectUserById(oaWork.getNUserId())!=null){
                    workTimeResps.add(WorkTimeResp.builder()
                            .id(oaWork.getNUserId())
                            .name(userMapper.selectUserById(oaWork.getNUserId()).getCRealName())
                            .deptId(userMapper.selectUserById(oaWork.getNUserId()).getNDeptId())
                            .workTime(oaWork.getCWorkTime()).build());
                    userIds.add(oaWork.getNUserId());
                }
            }
            oaUsers.forEach(oaUser -> {
                if(!userIds.contains(oaUser.getNUserId())){
                    workTimeResps.add(WorkTimeResp.builder().id(oaUser.getNUserId())
                            .name(oaUser.getCRealName())
                            .deptId(oaUser.getNDeptId())
                            .workTime(0.00).build());
                }
            });
        }

        if (role.contains("MANAGER")){
            QueryWrapper<OaUser> oaUserQueryWrapper = new QueryWrapper<>();
            oaUserQueryWrapper.eq("n_user_id", userId);
            OaUser oaUser = userMapper.selectOne(oaUserQueryWrapper);
            List<WorkTimeResp> collect = workTimeResps.stream().filter(oa -> oa.getDeptId() == oaUser.getNDeptId()).collect(Collectors.toList());
            return collect;
        }

        return workTimeResps;
    }

    @Override
    public List<TaskRateResp> getTaskRate(HttpServletRequest request) {
        String role = jwtUtil.extractUserRole(request);
        Long userId = jwtUtil.extractUserId(request);
        List<OaUser> oaUsers = userMapper.selectList(null);
        List<TaskRateResp> taskRateResps = new ArrayList<TaskRateResp>();
        if(oaUsers.size() != 0){
            oaUsers.forEach(oaUser -> {
                List<TaskResp> myTaskList = taskService.getMyTaskList(oaUser.getNUserId());
                //用户id查询自己的任务列表不为空
                if(myTaskList.size() != 0){
                    TaskRateResp taskRateResp = TaskRateResp.builder().id(oaUser.getNUserId())
                            .name(oaUser.getCRealName())
                            .deptId(oaUser.getNDeptId()).build();
                    // 总任务数
                    int totalTasks = myTaskList.size();
                    // 待办任务数
                    long pendingTasks = myTaskList.stream().filter(task -> task.getState().equals("待办")).count();
                    // 进行中任务数
                    long inProgressTasks = myTaskList.stream().filter(task -> task.getState().equals("进行中")).count();
                    // 计算任务完成率
                    double completionRate = (inProgressTasks * 0.5 + (totalTasks - pendingTasks - inProgressTasks)) / totalTasks;
                    // 保留两位小数并转换为百分比
                    double formattedCompletionRate = Math.round(completionRate * 10000.0) / 100.0; // 保留两位小数
                    String percentageOutput = formattedCompletionRate + "%"; // 加上百分号
                    taskRateResp.setRate(percentageOutput);
                    taskRateResps.add(taskRateResp);
                }else{
                    taskRateResps.add(TaskRateResp.builder().id(oaUser.getNUserId())
                            .name(oaUser.getCRealName())
                                    .deptId(oaUser.getNDeptId())
                            .rate("无任务").build());
                }
            });
            if(role.contains("MANAGER")){
                QueryWrapper<OaUser> oaUserQueryWrapper = new QueryWrapper<>();
                oaUserQueryWrapper.eq("n_user_id", userId);
                OaUser oaUser = userMapper.selectOne(oaUserQueryWrapper);
                return taskRateResps.stream().filter(oa->oa.getDeptId() == oaUser.getNDeptId()).collect(Collectors.toList());
            }

        }
        return taskRateResps;
    }

    @Override
    public List<PerformanceResp> getPerformance(HttpServletRequest request) {
        List<TaskRateResp> taskRate = getTaskRate(request);
        List<WorkTimeResp> workTime = getWorkTime(request);
        HashMap<Long,Double> taskScore = new HashMap<>();
        HashMap<Long,Double> workTimeScore = new HashMap<>();
        List<PerformanceResp> performanceResps = new ArrayList<>();
        //每个用户的任务绩效分
        for(TaskRateResp taskRateResp : taskRate){
            if(taskRateResp.getRate().equals("无任务")){
                taskScore.put(taskRateResp.getId(),50.0);
            }else{
                String substring = taskRateResp.getRate().substring(0, taskRateResp.getRate().length() - 2);
                double decimalValue = Double.parseDouble(substring);
                taskScore.put(taskRateResp.getId(),decimalValue*0.01*50);
            }
        }
        LocalDate today = LocalDate.now();
        List<OaTimeStandards> oaTimeStandards = timeStandardMapper.selectList(null);
        LocalTime towork = oaTimeStandards.stream().filter(oa -> oa.getCType().equals("上班"))
                .collect(Collectors.toList()).get(0).getDtTime().toLocalTime();
        LocalTime afterwork = oaTimeStandards.stream().filter(oa -> oa.getCType().equals("下班"))
                .collect(Collectors.toList()).get(0).getDtTime().toLocalTime();
        Duration duration = Duration.between(towork, afterwork);
        //一天的工作时间
        double onedayworktime = (double) duration.toMinutes() / 60;
        //每个用户的工作时间绩效
        for(WorkTimeResp workTimeResp : workTime){
            QueryWrapper<OaUser> oaWorkQueryWrapper = new QueryWrapper<>();
            oaWorkQueryWrapper.eq("n_user_id",workTimeResp.getId());
            OaUser oaUser = userMapper.selectOne(oaWorkQueryWrapper);
            long workdays = calculateWorkdays(oaUser.getDtTime(), today);
            //应该工作的时间
            double v = workdays * onedayworktime;
            //实际工作时间
            double workTime1 = workTimeResp.getWorkTime();
            double finalResult = new BigDecimal(Math.round(workTime1 / v * 1000.00) / 1000.0 * 50).setScale(3, RoundingMode.HALF_UP).doubleValue();
            workTimeScore.put(workTimeResp.getId(),finalResult);
        }
        taskScore.forEach((k,v)->{
            double v1 = new BigDecimal(v + workTimeScore.get(k)).setScale(3, RoundingMode.HALF_UP).doubleValue();
            PerformanceResp build = PerformanceResp.builder()
                    .id(k)
                    .name(userMapper.selectUserById(k).getCRealName())
                    .score(String.valueOf(v1)).build();
            QueryWrapper<OaUser> oaUserQueryWrapper = new QueryWrapper<>();
            oaUserQueryWrapper.eq("n_user_id", k);
            OaUser oaUser = userMapper.selectOne(oaUserQueryWrapper);
            if(deptMapper.selectDeptById(oaUser.getNDeptId()) != null){
                build.setDeptName(deptMapper.selectDeptById(oaUser.getNDeptId()).getCDeptName());
            }
            performanceResps.add(build);
        });
        return performanceResps;
    }

    @Override
    public List<UseSituationResp> getUseSituation() {
        List<OaLog> oaLogs = logMapper.selectList(null);
        List<UseSituationResp> useSituationResps = new ArrayList<>();
        long findHome = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findHome")).count()+
                oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("handleLogin")).count();
        useSituationResps.add(UseSituationResp.builder().name("首页").count(findHome).build());
        long findDept = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findDept")).count();
        useSituationResps.add(UseSituationResp.builder().name("部门管理").count(findDept).build());
        long findPosition = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findPosition")).count();
        useSituationResps.add(UseSituationResp.builder().name("职位管理").count(findPosition).build());
        long findMember = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findMember")).count();
        useSituationResps.add(UseSituationResp.builder().name("人员管理").count(findMember).build());
        long findTask = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findTask")).count();
        useSituationResps.add(UseSituationResp.builder().name("任务管理").count(findTask).build());
        long findMyTask = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findMyTask")).count();
        useSituationResps.add(UseSituationResp.builder().name("我的任务").count(findMyTask).build());
        long findSchedule = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findSchedule")).count();
        useSituationResps.add(UseSituationResp.builder().name("日程管理").count(findSchedule).build());
        long findMySchedule = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findMySchedule")).count();
        useSituationResps.add(UseSituationResp.builder().name("我的日程").count(findMySchedule).build());
        long findBoardroom = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findBoardroom")).count();
        useSituationResps.add(UseSituationResp.builder().name("会议室管理").count(findBoardroom).build());
        long findNotice = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findNotice")).count();
        useSituationResps.add(UseSituationResp.builder().name("通知管理").count(findNotice).build());
        long findNoticeList = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findNoticeList")).count();
        useSituationResps.add(UseSituationResp.builder().name("通知列表").count(findNoticeList).build());
        long findVacation = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findVacation")).count();
        useSituationResps.add(UseSituationResp.builder().name("请假管理").count(findVacation).build());
        long findAttendanceList = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findAttendanceList")).count();
        useSituationResps.add(UseSituationResp.builder().name("请假列表").count(findAttendanceList).build());
        long findAttendanceManage = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findAttendanceManage")).count();
        useSituationResps.add(UseSituationResp.builder().name("考勤管理").count(findAttendanceManage).build());
        long findReportList = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findReportList")).count();
        useSituationResps.add(UseSituationResp.builder().name("报表列表").count(findReportList).build());
        long findApprove = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findApprove")).count();
        useSituationResps.add(UseSituationResp.builder().name("审批管理").count(findApprove).build());
        long findFile = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findFile")).count();
        useSituationResps.add(UseSituationResp.builder().name("文件管理").count(findFile).build());
        long findAutoanswer = oaLogs.stream().filter(oaLog -> oaLog.getCMethodName().equals("findAutoanswer")).count();
        useSituationResps.add(UseSituationResp.builder().name("自动回复机器人").count(findAutoanswer).build());
        System.out.println("模块使用情况"+useSituationResps);
        return useSituationResps;
    }

    public static long calculateWorkdays(LocalDate startDate, LocalDate endDate) {
        long workdaysCount = 0;

        // 从开始日期到结束日期逐日检查
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            // 检查是否是工作日（不在周六和周日）
            if (isWeekday(date)) {
                workdaysCount++;
            }
        }
        return workdaysCount;
    }

    // 判断是否为工作日（周一到周五）
    private static boolean isWeekday(LocalDate date) {
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
    }
}
